package com.qk.management.scheduled;

import com.aliyun.oss.OSSException;
import com.qk.common.config.AliOSSProperties;
import com.qk.common.util.AliYunOSSOperators;
import com.qk.management.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 *
 *
 * @author blusr
 * @version 1.0
 * @date 2025/10/10 20:50
 */
@Slf4j
@Component
@SuppressWarnings("all")
public class CleanRedundantFiles {
    @Autowired
    private AliYunOSSOperators aliYunOSSOperators;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private AliOSSProperties aliOSSProperties;

    /**
     * 清理不在数据库中的OSS文件
     * 功能：查找OSS存储中存在但数据库中不存在的文件并删除它们
     */
    public void cleanupOrphanedOssFiles() {
        try {
            log.info("开始清理孤立的OSS文件");

            // 1. 获取OSS中的所有文件列表
            List<String> ossFileList = aliYunOSSOperators.getFileList();
            ossFileList.forEach(System.out::println);
            log.info("从OSS获取到{}个文件", ossFileList.size());

            if (ossFileList.isEmpty()) {
                log.info("OSS中没有文件，无需清理");
                return;
            }

            // 2. 获取数据库中存储的文件列表，使用Set提高查找效率
            Set<String> dbFileSet = getUserImageFileNames();
            log.info("从数据库获取到{}个文件引用", dbFileSet.size());

            // 3. 找出OSS中存在但数据库中不存在的文件
            List<String> orphanedFiles = findOrphanedFiles(ossFileList, dbFileSet);
            log.info("发现{}个孤立文件需要清理", orphanedFiles.size());

            // 4. 批量删除孤立文件
            if (!orphanedFiles.isEmpty()) {
                deleteOrphanedFiles(orphanedFiles);
            }

            log.info("OSS文件清理完成");
        } catch (Exception e) {
            log.error("清理OSS文件时发生错误: {}", e.getMessage(), e);
        }
    }

    /**
     * 从数据库获取用户图片文件名，存储在Set中以提高查找效率
     */
    private Set<String> getUserImageFileNames() {
        List<String> imageUrls = userMapper.selectImageList();
        String targetBucketName = aliOSSProperties.getBucket_name();

        return imageUrls.stream()
                .map(url -> extractFileNameFromUrl(url, targetBucketName))
                .filter(Objects::nonNull) // 过滤掉无法解析的URL
                .collect(Collectors.toSet());
    }

    /**
     * 从URL中提取文件名
     * @param url 完整的文件URL
     * @param targetBucketName 目标Bucket名称
     * @return 提取的文件名，如果URL不符合格式或不属于目标Bucket则返回null
     */
    private String extractFileNameFromUrl(String url, String targetBucketName) {
        try {
            String[] parts = url.split("/");
            if (parts.length >= 4) {
                String bucketPart = parts[2].split("\\.")[0];
                if (Objects.equals(targetBucketName, bucketPart)) {
                    return parts[3];
                }
            }
            return null;
        } catch (Exception e) {
            log.warn("解析URL失败: {}", url, e);
            return null;
        }
    }

    /**
     * 查找OSS中存在但数据库中不存在的文件
     */
    private List<String> findOrphanedFiles(List<String> ossFiles, Set<String> dbFiles) {
        return ossFiles.stream()
                .filter(file -> !dbFiles.contains(file))
                .collect(Collectors.toList());
    }

    /**
     * 删除孤立文件
     */
    private void deleteOrphanedFiles(List<String> filesToDelete) {
        int successCount = 0;
        int failCount = 0;

        for (String fileName : filesToDelete) {
            try {
                aliYunOSSOperators.deleteFile(fileName);
                successCount++;
                log.debug("成功删除文件: {}", fileName);
            } catch (OSSException e) {
                failCount++;
                log.error("删除文件失败[{}]: {}", fileName, e.getMessage());
            }
        }

        log.info("文件删除结果: 成功{}个, 失败{}个", successCount, failCount);
    }
}
